package com.whmskj.xjlhsc.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.whmskj.xjlhbc.db.DataSourceType;
import com.whmskj.xjlhbc.db.DynamicDataSourceContextHolder;
import com.whmskj.xjlhsc.controller.vo.JtjcVo;
import com.whmskj.xjlhsc.entity.CatalogueOfGy02Stations;
import com.whmskj.xjlhsc.entity.Sb02EquipmentCounterAccount;
import com.whmskj.xjlhsc.entity.Shachangsbhouryield;
import com.whmskj.xjlhsc.mapper.CatalogueOfGy02StationsMapper;
import com.whmskj.xjlhsc.service.Sb02EquipmentCounterAccountService;
import com.whmskj.xjlhsc.service.ScHomeService;
import com.whmskj.xjlhsc.service.ShachangsbhouryieldService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class ScHomeServiceImpl implements ScHomeService {

    @Autowired
    private ShachangsbhouryieldService shachangsbhouryieldService;

    @Autowired
    private Sb02EquipmentCounterAccountService sb02EquipmentCounterAccountService;

    @Autowired
    private CatalogueOfGy02StationsMapper catalogueOfGy02StationsMapper;


    @Override
    public Object getCl(String process) {
        List<String> processList = new ArrayList<>();
        if(process.equals("并条")){
            processList = Arrays.asList("头并", "条卷", "精梳", "末并");
        }else{
            processList.add(process);
        }
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> brMap = new HashMap<>();
        Map<String, Object> byMap = new HashMap<>();
        Map<String, Object> bnMap = new HashMap<>();
        List<Map<String, Object>> brChartList = new ArrayList<>();
        List<Map<String, Object>> byChartList = new ArrayList<>();
        List<Map<String, Object>> bnChartList = new ArrayList<>();
        DateTime date = DateUtil.date();
        String beginOfDay = DateUtil.beginOfDay(date).toString();
        String endOfDay = DateUtil.endOfDay(date).toString();
        String beginOfMonth = DateUtil.beginOfMonth(date).toString();
        String endOfMonth = DateUtil.endOfMonth(date).toString();
        String beginOfYear = DateUtil.beginOfYear(date).toString();
        String endOfYear = DateUtil.endOfYear(date).toString();

        List<Shachangsbhouryield> clList = getClList(processList, beginOfDay, endOfDay);
        List<Shachangsbhouryield> clList1 = getClList(processList, beginOfMonth, endOfMonth);
        List<Shachangsbhouryield> clList2 = getClList(processList, beginOfYear, endOfYear);
        Map<String, List<CatalogueOfGy02Stations>> pzMapList = getPz(processList);
        Set<Map.Entry<String, List<CatalogueOfGy02Stations>>> entries = pzMapList.entrySet();
        for(Map.Entry<String, List<CatalogueOfGy02Stations>> entry : entries){
            String pz = entry.getKey();
            List<String> jthList = entry.getValue().stream().map(CatalogueOfGy02Stations::getStationNumber).toList();
            LambdaQueryWrapper<Sb02EquipmentCounterAccount> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(Sb02EquipmentCounterAccount::getProcess, processList)
                    .in(Sb02EquipmentCounterAccount::getPlatform, jthList);
            List<Sb02EquipmentCounterAccount> list = sb02EquipmentCounterAccountService.list(lambdaQueryWrapper);
            List<Integer> mesIds = list.stream().map(Sb02EquipmentCounterAccount::getId).toList();
            double sum = clList.stream().filter(f -> mesIds.contains(f.getMesid())).mapToDouble(m -> NumberUtil.parseDouble(m.getActualyieldkg(), 0.0)).sum();
            double sum1 = clList1.stream().filter(f -> mesIds.contains(f.getMesid())).mapToDouble(m -> NumberUtil.parseDouble(m.getActualyieldkg(), 0.0)).sum();
            double sum2 = clList2.stream().filter(f -> mesIds.contains(f.getMesid())).mapToDouble(m -> NumberUtil.parseDouble(m.getActualyieldkg(), 0.0)).sum();
            Map<String, Object> chartMap = new HashMap<>();
            chartMap.put("name", pz);
            chartMap.put("value", Math.round(sum/1000.0 * 100) / 100.0);//kg转吨两位小数
            brChartList.add(chartMap);
            chartMap = new HashMap<>();
            chartMap.put("name", pz);
            chartMap.put("value", Math.round(sum1/1000.0 * 100) / 100.0);
            byChartList.add(chartMap);
            chartMap = new HashMap<>();
            chartMap.put("name", pz);
            chartMap.put("value", Math.round(sum2/1000.0 * 100) / 100.0);
            bnChartList.add(chartMap);
        }
        List<String> hours = getHours();
        List<String> months = getMonths();
        List<String> years = getYears();
        List<Map<String, Object>> brChartList1 = hours.stream().map(item -> {
            double sum = clList.stream().filter(f -> f.getDay().startsWith(item)).mapToDouble(m -> NumberUtil.parseDouble(m.getActualyieldkg(), 0.0)).sum();
            Map<String, Object> chartMap = new HashMap<>();
            chartMap.put("name", item);
            chartMap.put("value", Math.round(sum/1000.0 * 100) / 100.0);
            return chartMap;
        }).toList();
        List<Map<String, Object>> byChartList1 = months.stream().map(item -> {
            double sum = clList1.stream().filter(f -> f.getDay().contains(item)).mapToDouble(m -> NumberUtil.parseDouble(m.getActualyieldkg(), 0.0)).sum();
            Map<String, Object> chartMap = new HashMap<>();
            chartMap.put("name", item);
            chartMap.put("value", Math.round(sum/1000.0 * 100) / 100.0);
            return chartMap;
        }).toList();
        List<Map<String, Object>> bnChartList1 = years.stream().map(item -> {
            double sum = clList2.stream().filter(f -> f.getDay().contains(item)).mapToDouble(m -> NumberUtil.parseDouble(m.getActualyieldkg(), 0.0)).sum();
            Map<String, Object> chartMap = new HashMap<>();
            chartMap.put("name", item);
            chartMap.put("value", Math.round(sum/1000.0 * 100) / 100.0);
            return chartMap;
        }).toList();

        brMap.put("totalCl", getCl(processList,beginOfDay,endOfDay));
        brMap.put("chart1", brChartList);
        brMap.put("chart2", brChartList1);
        byMap.put("totalCl", getCl(processList,beginOfMonth,endOfMonth));
        byMap.put("chart1", byChartList);
        byMap.put("chart2", byChartList1);
        bnMap.put("totalCl", getCl(processList,beginOfYear,endOfYear));
        bnMap.put("chart1", bnChartList);
        bnMap.put("chart2", bnChartList1);
        map.put("br", brMap);
        map.put("by", byMap);
        map.put("bn", bnMap);
        return map;
    }

    @Override
    public Object getJtjc() {
        try {
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SC.name());
            JtjcVo v = sb02EquipmentCounterAccountService.selectSmJtjc();
            JtjcVo v1 = sb02EquipmentCounterAccountService.selectBtJtjc();
            JtjcVo v2 = sb02EquipmentCounterAccountService.selectCsJtjc();
            JtjcVo v3 = sb02EquipmentCounterAccountService.selectXsJtjc();
            JtjcVo v4 = sb02EquipmentCounterAccountService.selectLtJtjc();

            JtjcVo v0 = new JtjcVo();
            v0.setName("全部");
            v0.setTotal(v.getTotal()+v1.getTotal()+v2.getTotal()+v3.getTotal()+v4.getTotal());
            v0.setXl((v.getXl()+v1.getXl()+v2.getXl()+v3.getXl()+v4.getXl())/5);
            v0.setLt(v.getLt()+v1.getLt()+v2.getLt()+v3.getLt()+v4.getLt());
            v0.setYx(v.getYx()+v1.getYx()+v2.getYx()+v3.getYx()+v4.getYx());
            v0.setKjl((v.getKjl()+v1.getKjl()+v2.getKjl()+v3.getKjl()+v4.getKjl())/5);
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
            return List.of(v0,v,v1,v2,v3,v4);
        }finally {
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
        }
    }

    @Override
    public Object getYgxx() {
        Map<String, Object> resultMap = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        map.put("bzyg", 0);
        map.put("dqpb", 0);
        map.put("bypj", 0);
        map.put("byjl", 0);
        map.put("byfk", 0);
        map.put("byjy", 0);
        resultMap.put("top", map);
        Map<String, Object> chartMap = new HashMap<>();
        Map<String, Object> chartMap1 = new HashMap<>();
        Map<String, Object> chartMap2 = new HashMap<>();
        List<String> processList = Arrays.asList("清花", "梳棉", "头并", "末并", "粗纱", "细纱", "络筒");
        List<String> bList = Arrays.asList("早班","中班","晚班");
        List<String> months = getMonths();
        List<String> years = getYears();
        List<Map<String, Object>> list = getList(processList);
        List<Map<String, Object>> list1 = getList(months);
        List<Map<String, Object>> list2 = getList(bList);
        List<Map<String, Object>> list3 = getList(years);
        chartMap.put("leftChart", list);
        chartMap.put("rightChart", list1);
        chartMap1.put("leftChart", list);
        chartMap1.put("rightChart", list2);
        chartMap2.put("leftChart", list);
        chartMap2.put("rightChart", list3);
        resultMap.put("chart1", chartMap);
        resultMap.put("chart2", chartMap1);
        resultMap.put("chart3", chartMap2);
        return resultMap;
    }

    private static List<Map<String, Object>> getList(List<String> processList) {
        return processList.stream().map(item -> {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("name", item);
            map1.put("value", 10);
            return map1;
        }).toList();
    }

    //机台品种
    private Map<String,List<CatalogueOfGy02Stations>> getPz(List<String> processList){
        LambdaQueryWrapper<CatalogueOfGy02Stations> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CatalogueOfGy02Stations::getProcess, processList);
        List<CatalogueOfGy02Stations> catalogueOfGy02Stations = catalogueOfGy02StationsMapper.selectList(wrapper);
        return catalogueOfGy02Stations.stream().collect(Collectors.groupingBy(CatalogueOfGy02Stations::getVarieties));
    }

    private List<Shachangsbhouryield> getClList(List<String> processList, String begin, String end){
        LambdaQueryWrapper<Sb02EquipmentCounterAccount> sbLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sbLambdaQueryWrapper.in(Sb02EquipmentCounterAccount::getProcess, processList);
        List<Sb02EquipmentCounterAccount> sbList = sb02EquipmentCounterAccountService.list(sbLambdaQueryWrapper);
        List<Integer> sbIds = sbList.stream().map(Sb02EquipmentCounterAccount::getId).toList();
        if(!sbIds.isEmpty()){
            LambdaQueryWrapper<Shachangsbhouryield> shachangsbhouryieldLambdaQueryWrapper = new LambdaQueryWrapper<>();
            shachangsbhouryieldLambdaQueryWrapper.in(Shachangsbhouryield::getMesid, sbIds);
            shachangsbhouryieldLambdaQueryWrapper.between(Shachangsbhouryield::getDay, begin,end);
            return shachangsbhouryieldService.list(shachangsbhouryieldLambdaQueryWrapper);
        }
        return new ArrayList<>();
    }

    private String getCl(List<String> processList,String begin,String end){
        List<Shachangsbhouryield> list = getClList(processList, begin, end);
        double value = list.stream().mapToDouble(m -> NumberUtil.parseDouble(m.getActualyieldkg(), 0.0)).sum();
        return String.format("%.2f", value/1000.0);
    }
    private static List<String> getHours(){
        List<String> hours = new ArrayList<>();
        hours.add(LocalDate.now().toString());
        return hours;
    }

    private static List<String> getMonths(){
        LocalDate start = LocalDate.now().withDayOfMonth(1);
        LocalDate end = LocalDate.now();
        List<String> list = new ArrayList<>();
        while(start.isBefore(end)){
            list.add(start.toString());
            start = start.plusDays(1);
        }
        return list;
    }

    private static List<String> getYears(){
        LocalDate start = LocalDate.now().withMonth(1).withDayOfMonth(1);
        LocalDate end = LocalDate.now();
        List<String> list = new ArrayList<>();
        while(start.isBefore(end)){
            list.add(start.toString().substring(0,7));
            start = start.plusMonths(1);
        }
        return list;
    }
}
